package main

import (
	"flag"
	"fmt"
	"gse/transport/udp/connection"
	"io/ioutil"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"strings"
	"time"
)

func main() {
	flagset := flag.NewFlagSet("parameters", flag.ExitOnError)
	var sAddr string
	flagset.StringVar(&sAddr, "s", "", "server address, e.g. 127.0.0.1:3131")
	var dataFile string
	flagset.StringVar(&dataFile, "d", "", "the file that contains the data to be sent.")
	var requireAck bool
	flagset.BoolVar(&requireAck, "a", false, "whether requires the server to ack each data packet.")
	var keepAlive bool
	flagset.BoolVar(&keepAlive, "k", false, "keep alive.")
	var dataSendRate int
	flagset.IntVar(&dataSendRate, "n", 14000, "packets sent per second")
	var retryInterval int
	flagset.IntVar(&retryInterval, "i", 1000, "interval of retries for failed sends.")
	flagset.Parse(os.Args[1:])
	go http.ListenAndServe("0.0.0.0:6365", nil)
	addr, err := net.ResolveUDPAddr("udp4", sAddr)
	if err != nil {
		panic(err)
	}
	c, err := connection.Connnect(addr)
	if err != nil {
		panic(err)
	}
	go getResponse(c)
	go getPing(c)
	fmt.Printf("Connected to remote server[%v] with local address[%v]\n", c.RemoteAddr(), c.LocalAddr())
	if keepAlive {
		c.KeepAlive()
	}

	cfg := c.GetConfig()
	cfg.PacketSendRate = dataSendRate
	cfg.SendRetryInterval = retryInterval
	cfg.AckTimeout = retryInterval / 3
	c.SetConfig(cfg)
	files := strings.Split(dataFile, ",")
	for _, dataFile := range files {
		data, err := ioutil.ReadFile(dataFile)
		fmt.Println("bytes to send:", len(data))
		if err != nil {
			panic(err)
		}
		var n int
		if requireAck {
			n, err = c.SendDataWithAck(data)
		} else {
			n, err = c.SendData(data)
		}

		fmt.Println(n, err)
	}
	if !keepAlive {
		return
	}

	ch := make(chan bool)
	<-ch
}

func getPing(conn *connection.Connection) {
	ticker := time.NewTicker(time.Second * 5)
	for {
		<-ticker.C

		duration, err := conn.Ping()
		prefix := "ping result: "
		data := []byte(fmt.Sprintf("%v, err: %v", duration, err))
		sep := strings.Repeat("=", len(data)+len(prefix)+6)
		fmt.Printf(`%v
|| %v %v ||
%v
`, sep, prefix, string(data), sep)
	}
}
func getResponse(conn *connection.Connection) {
	for {
		data, err := conn.ReadData()
		if err != nil {
			return
		}
		prefix := "server response: "
		sep := strings.Repeat("=", len(data)+len(prefix)+6)
		fmt.Printf(`%v
|| %v %v ||
%v
`, sep, prefix, string(data), sep)
	}
}
